package com.bit101.components {
	import com.bit101.components.Interface.IObject;
	
	import flash.display.DisplayObjectContainer;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.display.StageAlign;
	import flash.display.StageScaleMode;
	import flash.events.Event;
	import flash.filters.DropShadowFilter;
	import flash.utils.getDefinitionByName;
	import flash.utils.getQualifiedClassName;

	/**
	 * UI组件基类
	 * 定义坐标，大小，添加子对象(子类实现)，绘制UI,背景滤镜,舞台显示方式
	 * 实现自定义对象接口(equlas,getClassName,getClass,clone)
	 */	
	[Event(name="resize",type="flash.events.Event")]
	[Event(name="draw",type="flash.events.Event")]
	public class Component extends Sprite implements IObject{
		protected var _width:Number = 0;
		protected var _height:Number = 0;
		protected var _tag:int = -1;
		protected var _enabled:Boolean = true;
		public static const DRAW:String = "draw";

		public function Component(parent:DisplayObjectContainer = null, xpos:Number = 0, ypos:Number = 0){
			if (parent != null){
				parent.addChild(this);
			}
			move(xpos, ypos);
			init();
		}

		/**
		 * 初始化.
		 */
		protected function init():void {
			addChildren();
			invalidate();
		}

		/**
		 * 添加子对象抽象方法
		 * 由子类继承重写
		 */
		protected function addChildren():void {
		}

		/**
		 * 倒影滤镜
		 * @param dist 
		 * @param bool 
		 */
		protected function getShadow(dist:Number, bool:Boolean = false):DropShadowFilter {
			return new DropShadowFilter(dist, 45, Style.DROPSHADOW, 1, dist, dist, .3, 1, bool);
		}

		/**
		 * 时时监听侦事件
		 * 执行draw绘画组件大小
		 */
		protected function invalidate():void {
			this.addEventListener(Event.ENTER_FRAME, onInvalidate);
		}

		/**
		 * 设置舞台显示方式
		 */
		public static function initStage(stage:Stage):void {
			stage.align = StageAlign.TOP_LEFT;
			stage.scaleMode = StageScaleMode.NO_SCALE;
		}

		/**
		 * 设置坐标
		 * @param
		 * @param
		 */
		public function move(xpos:Number, ypos:Number):void {
			this.x = Math.round(xpos);
			this.y = Math.round(ypos);
		}

		/**
		 * 设置组件大小
		 * @param w 
		 * @param h 
		 */
		public function setSize(w:Number, h:Number):void {
			_width = w;
			_height = h;
			dispatchEvent(new Event(Event.RESIZE));
			invalidate();   //draw方法
		}

		/**
		 * Abstract draw function.
		 * 抽象绘制方法
		 * 派发Component.DRAW事件
		 */
		public function draw():void {
			this.dispatchEvent(new Event(Component.DRAW));
		}

		/**
		 * 帧事件侦听函数，执行draw方法
		 */
		protected function onInvalidate(event:Event):void {
			removeEventListener(Event.ENTER_FRAME, onInvalidate);
			draw();
		}

		/**
		 * 
		 * 实现IObject接口方法  
		 * 
		 */		
		public function equals(object:*):Boolean{
			return this==object;
		}
		/**对象的完全限定类名*/
		public final function getClassName():String{
			return getQualifiedClassName(this).replace("::",".");
		}
		/**返回类的类对象引用*/
		public final function getClass():Class{
			return getDefinitionByName(getClassName()) as Class;
		}
		public function clone():*{
			
		}
		override public function toString():String{
			return "[toString:" + getClassName() + "]";
		}
		
		///////////////////////////////////
		// getter/setters
		///////////////////////////////////
		/**
		 * 设置大小重新绘制UI 
		 * 派发resize事件
		 * @param w
		 */		
		override public function set width(w:Number):void {
			_width = w;
			invalidate();
			dispatchEvent(new Event(Event.RESIZE));
		}

		override public function get width():Number {
			return _width;
		}

		/**
		 * 设置大小重新绘制UI 
		 * @param h
		 */	
		override public function set height(h:Number):void {
			_height = h;
			invalidate();
			dispatchEvent(new Event(Event.RESIZE));
		}

		override public function get height():Number {
			return _height;
		}

		/**
		 * Sets/gets in integer that can identify the component.
		 * 设置组件的不同标识
		 */
		public function set tag(value:int):void {
			_tag = value;
		}

		public function get tag():int {
			return _tag;
		}

		override public function set x(value:Number):void {
			super.x = Math.round(value);
		}

		override public function set y(value:Number):void {
			super.y = Math.round(value);
		}
		
		/**
		 * UI可视设置1,0.5
		 * @param value
		 */		
		public function set enabled(value:Boolean):void {
			_enabled = value;
			mouseEnabled = mouseChildren = _enabled;
			tabEnabled = value;
			alpha = _enabled ? 1.0 : 0.5;
		}

		public function get enabled():Boolean {
			return _enabled;
		}
	}
}